﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <list>
#include <map>
#include <set>
#include <vector>
#include <functional>
#include <thread>
#include <mutex>
#include <atomic>
#include <assert.h>
using namespace std;

// 使用方法如下：
//#include <functional>
//int f(int a, int b)
//{
//	return a + b;
//}
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//class Plus
//{
//public:
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//
//int func(int x)
//{
//	return x;
//}
//
//int main()
//{
//	// 函数名(函数指针)
//	std::function<int(int, int)> func1 = f;
//	cout << func1(1, 2) << endl;
//	// 函数对象
//	std::function<int(int, int)> func2 = Functor();
//	cout << func2(1, 2) << endl;
//	// lamber表达式
//	std::function<int(int, int)> func3 = [](const int a, const int b)
//	{return a + b; };
//	cout << func3(1, 2) << endl;
//	// 类的成员函数
//	std::function<int(int, int)> func4 = &Plus::plusi;
//	cout << func4(1, 2) << endl;
//	std::function<double(Plus, double, double)> func5 = &Plus::plusd;
//	cout << func5(Plus(), 1.1, 2.2) << endl;
//
//	function<int(int)> f = func;
//
//	cout << typeid(Functor().operator()).name() << endl;
//
//	return 0;
//}

//void Func(int& x)
//{
//	cout << "func:左值引用" << endl;
//}
//
//void Func(const int& x)
//{
//	cout << "func:const 左值引用" << endl;
//}
//
//
//void Func(int&& x)
//{
//	cout << "func:右值引用" << endl;
//}
//
//void Func(const int&& x)
//{
//	cout << "func:const 右值引用" << endl;
//}
//
//void Fun(int& x)
//{
//	cout << endl;
//	Func(x);
//	cout << endl;
//	cout << "左值引用" << endl;
//}
//
//void Fun(const int& x)
//{
//	cout << endl;
//	Func(x);
//	cout << endl;
//	cout << "const 左值引用" << endl;
//}
//
//
//void Fun(int&& x)
//{
//	cout << endl;
//	Func(x);
//	cout << endl;
//	cout << "右值引用" << endl;
//}
//
//void Fun(const int&& x)
//{
//	cout << endl;
//	Func(x);
//	cout << endl;
//	cout << "const 右值引用" << endl;
//}
//
//// 模板中的&&不代表右值引用，而是万能引用，其既能接收左值又能接收右值。
//// 模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力，
//// 但是引用类型的唯一作用就是限制了接收的类型，后续使用中都退化成了左值，
//// 我们希望能够在传递过程中保持它的左值或者右值的属性, 就需要用我们下面学习的完美转发
//template<typename T>
//void PerfectForward(T&& t)
//{
//	Fun(t);
//}
//
//int main()
//{
//	PerfectForward(10); // 右值
//	cout << endl;
//
//	int a;
//	PerfectForward(a); // 左值
//	cout << endl;
//
//	PerfectForward(std::move(a)); // 右值
//	cout << endl;
//
//	const int b = 8;
//	PerfectForward(b); // const 左值
//	cout << endl;
//
//	PerfectForward(std::move(b)); // const 右值
//	cout << endl;
//	
//	return 0;
//}


//namespace bit
//{
//	class string
//	{
//	public:
//		typedef char* iterator;
//
//		iterator begin()
//		{
//			return _str;
//		}
//		iterator end()
//		{
//			return _str + _size;
//		}
//		string(const char* str = "")
//			:_size(strlen(str))
//			, _capacity(_size)
//		{
//			//cout << "string(char* str)" << endl;
//			_str = new char[_capacity + 1];
//			strcpy(_str, str);
//		}
//
//		// s1.swap(s2)
//		void swap(string& s)
//		{
//			::swap(_str, s._str);
//			::swap(_size, s._size);
//			::swap(_capacity, s._capacity);
//		}
//
//		// 拷贝构造
//		string(const string& s)
//			:_str(nullptr)
//		{
//			cout << "string(const string& s) -- 深拷贝" << endl;
//			string tmp(s._str);
//			swap(tmp);
//		}
//
//		// 赋值重载
//		string& operator=(const string& s)
//		{
//			cout << "string& operator=(string s) -- 深拷贝" << endl;
//			string tmp(s);
//			swap(tmp);
//			return *this;
//		}
//
//		// 移动构造
//		string(string&& s)
//			:_str(nullptr)
//			, _size(0)
//			, _capacity(0)
//		{
//			cout << "string(string&& s) -- 移动语义" << endl;
//			swap(s);
//		}
//
//		// 移动赋值
//		string& operator=(string&& s)
//		{
//			cout << "string& operator=(string&& s) -- 移动语义" << endl;
//			swap(s);
//			return *this;
//		}
//
//		~string()
//		{
//			delete[] _str;
//			_str = nullptr;
//		}
//		char& operator[](size_t pos)
//		{
//			assert(pos < _size);
//			return _str[pos];
//		}
//		void reserve(size_t n)
//		{
//			if (n > _capacity)
//			{
//				char* tmp = new char[n + 1];
//				strcpy(tmp, _str);
//				delete[] _str;
//				_str = tmp;
//				_capacity = n;
//			}
//		}
//		void push_back(char ch)
//		{
//			if (_size >= _capacity)
//			{
//				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
//				reserve(newcapacity);
//			}
//			//比特就业课左值引用的使用场景：
//			//	做参数和做返回值都可以提高效率。
//			//	左值引用的短板：
//			//	但是当函数返回对象是一个局部变量，出了函数作用域就不存在了，就不能使用左值引用返回，
//			//	只能传值返回。例如：bit::string to_string(int value)函数中可以看到，这里只能使用传值返回，
//			//	传值返回会导致至少1次拷贝构造(如果是一些旧一点的编译器可能是两次拷贝构造)。
//				_str[_size] = ch;
//			++_size;
//			_str[_size] = '\0';
//		}
//		//string operator+=(char ch)
//		string& operator+=(char ch)
//		{
//			push_back(ch);
//			return *this;
//		}
//		const char* c_str() const
//		{
//			return _str;
//		}
//	private:
//		char* _str;
//		size_t _size;
//		size_t _capacity; // 不包含最后做标识的\0
//	};
//}
//
//void func1(bit::string s)
//{}
//
//void func2(const bit::string& s)
//{}
//int main()
//{
//	bit::string s1("hello world");
//	// func1和func2的调用我们可以看到左值引用做参数减少了拷贝，提高效率的使用场景和价值
//	func1(s1);
//	func2(s1);
//
//	// string operator+=(char ch) 传值返回存在深拷贝
//	// string& operator+=(char ch) 传左值引用没有拷贝提高了效率
//	
//	s1 += '!';
//	return 0;
//}

//int main()
//{
//
//	int&& ra1 = 10;
//
//	int a = 10;
//	int&& ra2 = move(a);
//
//	ra2 = 20;
//
//	cout << ra2 << endl;
//	cout << a << endl;
//
//
//	return 0;
//}

//template<class T1,class T2>
//auto f(T1 t1, T2 t2) -> decltype(t1* t2)
//{
//
//	return t1 * t2;
//}
//
//int main()
//{
//	cout << f(3, 2) << endl;
//	return 0;
//}


//template<class T1, class T2>
//void func(T1 t1, T2 t2)
//{
//	decltype(t1 * t2) t;
//	cout << typeid(t).name() << endl;
//}
//
//int main()
//{
//	//func(10, 20);
//
//	int n = 10;
//	int& rn = n;
//	const int& cra = n;
//
//	decltype(n) n1;			//int
//	decltype((n)) n2 = n;	//int&
//	decltype(rn) n3 = n;	//int&
//	decltype(cra) n4 = n;	//const int&
//
//	n = 20;
//
//	return 0;
//}


//int main()
//{
//	decltype(1 * 10) y;
//
//	cout << typeid(y).name() << endl;
//
//	int a = 10;
//	decltype(&a) pa;
//	cout << typeid(pa).name() << endl;
//
//}


//int main()
//{
//	map<int, string> m({ { 1,"a" }, { 2,"b" } });
//
//	vector<int> v = { 1,2,3 };
//
//	v = { 3,2,1 };
//
//	return 0;
//}

//void func(const initializer_list<int>& list)
//{
//	for (auto i = list.begin(); i != list.end(); ++i)
//	{
//		cout << *i << endl;
//	}
//}
//int main()
//{
//	func({ 1,2,3,4,5 });
//	return 0;
//}


//class A
//{
//public:
//	A(int x,int y)
//		:_x(x)
//		,_y(y)
//	{}
//private:
//	int _x;
//	int _y;
//};
//
//int main()
//{
//	int i = { 1 };
//
//	double d{ 1.1 };
//	
//	A a = { 1,2 };
//	A b{ 2,3 };
//
//	int* arr1 = new int[5]{ 1 };
//	int* arr2 = new int[5] { 1,1,1,1,1 };
//
//
//	return 0;
//}


//int main()
//{
//	bool flag = true;//true 偶数
//	int x = 0;
//	mutex m;
//
//	condition_variable cond;
//
//	thread t1([&]
//		{
//			while (x < 100)
//			{
//				unique_lock<mutex> lock(m);
//				cond.wait(lock, [&] {return flag;});	//返回false 阻塞；true 不阻塞
//
//
//				cout << x << endl;		
//
//				flag = true;
//				x += 1;
//
//				cond.notify_one();
//			}
//		}
//	);
//
//	thread t2([&]
//		{
//			while (x < 100)
//			{
//				unique_lock<mutex> lock(m);
//				while (!flag)
//				{
//					cond.wait(lock);
//				}
//				cout << x << endl;
//				flag = false;
//				x += 1;
//
//				cond.notify_one();
//			}
//		}
//	);
//
//	t1.join();
//	t2.join();
//
//
//	return 0;
//}



//int main()
//{
//	mutex mtx;
//	int x = 0;
//	atomic<int> xx = 0;
//	vector<thread> threads(5);
//
//	auto func = [&] {
//		//unique_lock<mutex> m(mtx);
//		for (int i = 0; i < 100000 ; ++i)
//			++xx;
//	};
//
//	for (auto& t : threads)
//	{
//		t = thread(func);
//	}
//
//	for (auto& t : threads)
//	{
//		t.join();
//	}
//
//	cout << xx << endl;
//
//	return 0;
//}


//int main()
//{
//	int x = 0;
//	mutex mtx;
//
//	thread t1([&] {
//		mtx.lock();
//		for (int i = 0; i < 100000; ++i)
//		
//			x++;
//		mtx.unlock();
//		}
//	);
//
//	thread t2([&] {
//		mtx.lock();
//		for (int i = 0; i < 100000; ++i)
//			x++;
//		mtx.unlock();
//		}
//	);
//
//	t1.join();
//	t2.join();
//
//
//	cout << x << endl;
//
//	return 0;
//}


//void func(int n,int& rx,mutex& m)
//{
//	m.lock();
//
//	for (int i = 1; i <= n; ++i)
//	{
//		rx++;
//	}
//	m.unlock();
//
//}
//
//int main()
//{
//	mutex m;
//	int rx = 0;
//
//	thread t1(func,100000,ref(rx),ref(m));
//	thread t2(func,200000,ref(rx),ref(m));
//
//
//
//	t1.join();
//	t2.join();
//
//	cout << rx << endl;
//
//	return 0;
//}

//int main()
//{
//	map<int, int> m1;
//	m1[0]++;
//	m1[1]++;
//
//	for (int i = 0;i < 2; ++i)
//		cout << m1[i] << endl;
//	return 0;
//}

//int fx(int x, int y)
//{
//	cout << "血量：" << x << " 蓝耗：" << y << endl;
//	return x + y;
//}
//
//class Sub
//{
//public:
//	int sub(int x, int y)
//	{
//		cout << "血量：" << x << " 蓝耗：" << y << endl;
//		return x + y;
//	}
//};
//
//int main()
//{
//	auto f1 = bind(fx, placeholders::_1, placeholders::_2);
//	f1(10, 20);
//	
//	auto f2 = bind(fx, placeholders::_2, placeholders::_1);
//	f2(10, 20);
//
//
//	Sub s;
//	auto f3 = bind(&Sub::sub, &s,placeholders::_1, placeholders::_2);
//	auto f4 = bind(&Sub::sub, Sub(), placeholders::_1, placeholders::_2);
//	f3(10, 20);
//	f4(10, 20);
//
//	return 0;
//}

//int subi(int x, int y)
//{
//	cout << x << "+" << y << "=" << x + y << endl;
//	return x + y;
//
//}
//
//class Sub
//{
//public:
//	static int add(int x, int y) 
//	{
//		cout << x << "+" << y << "=" << x + y << endl;
//		return x + y;
//	}
//
//	int sub(int x,int y)
//	{
//		cout << x << "+" << y << "=" << x + y << endl;
//		return x + y;
//	}
//
//	int operator()(int x, int y)
//	{
//		cout << x << "+" << y << "=" << x + y << endl;
//		return x + y;
//
//	}
//};
//
//
//template<class T>
//void func(T n)
//{
//	cout << "t" << endl;
//	cout << n << endl;
//}
//
//void func(double n)
//{
//	cout << n << endl;
//}
//
//int main()
//{
//	// 1. 普通函数
//	function<int(int, int)> f1 = subi;
//
//	// 2. 仿函数
//	Sub s;
//	function<int(int, int)> f2 = Sub();
//
//	// 3. lambda表达式
//	function<int(int, int)> f3 = [](int x, int y) {
//		cout << x << "+" << y << "=" << x + y << endl;
//		return x + y;
//	};
//
//	// 成员函数的函数指针  &类域::成员函数名
//	   
//	// 4. 静态成员函数
//	function<int(int, int)> f4 = &Sub::add;
//
//	// 5. 非静态成员函数
//	function<int(Sub*,int, int)> f5 = &Sub::sub;
//	function<int(Sub, int, int)> f6 = &Sub::sub;
//
//
//	f1(1, 2);
//	f2(1, 2);
//	f3(1, 2);
//	f4(1, 2);
//	f5(&s,1, 2);
//	f6(Sub(),1, 2);
//
//	func(10);
//
//
//	return 0;
//}

//struct Point
//{
//	int _x;
//	int _y;
//};
//
//class A
//{
//public:
//	A(int x)
//		: _x(x)
//		, _y(x)
//	{}
//
//	A(int x, int y)
//		: _x(x)
//		, _y(y)
//	{}
//
//private:
//	int _x;
//	int _y;
//};
//
//
//int main()
//{
//	//C语言 ， C++98兼容的C
//	int arr1[] = { 1,2,3 };
//	int arr2[5] = { 0 };
//	Point p = { 1,2 };
//
//	//C++11 
//	 // 单参数的隐式类型转换
//	A a1 = 1;
//	A a3 = { 1 };
//	A a4{ 4 };
//	 //多参数的隐式类型转换
//	A a2 = { 1,2 };
//	A a5{ 1,2 };
//
//	const A& ra = { 2,2 };
//
//	int i{ 1 };
//	int i1 = { 2 };
//
//	return 0;
//}

//int main()
//{
//
//	//构造 调用 vector(initializer_list）
//	vector<int> v2({ 1,2,3 });
//
//	//隐式类型转换   构造临时对象 ，在调用拷贝构造 -> 编译器优化成 构造函数
//	vector<int> v1 = { 1,2,3 };
//	vector<int> v3{ 1,2,3 };
//
//	//综合一下 {} 和 initializer_list
//	 //里面的{},是多参数的隐式类型转换 , 外面的 {} 是 initializer_list
//	map<string, string> m = { {"sort","paixu"} , {"jaj" , "jaj"} };
//
//
//	return 0;
//}
//int main()
//{
//	int i = 0;
//	auto x = i;
//
//	x++;
//
//	auto& rx = x;
//	rx++;
//
//	auto& y = rx;
//	y++;
//
//	return 0;
//}
//int main()
//{
//	int i = 0;
//	int* p = &i;
//
//	cout << &i << endl;
//	cout << &(*p) << endl;
//	return 0;
//}
//int main()
//{
//	int&& rr = 10;
//	int i = rr;
//	int& r = rr;
//
//	cout << r << endl;
//	r++;
//
//	cout << rr << endl;
//
//	string s1("111");
//	string&& rs = move(s1);
//
//	return 0;
//}

//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<typename T>
//void PerfectForward(T&& t)
//{
//	Fun(forward<T>(t));
//}
//int main()
//{
//	PerfectForward(10);
//	int a;
//	PerfectForward(a); 
//	PerfectForward(std::move(a));
//	const int b = 8;
//	PerfectForward(b); 
//	PerfectForward(std::move(b)); // const 右值
//	return 0;
//}

//
//int main()
//{
//	/*auto add = [](int a, int b)->int {return a + b;};
//
//	auto func = [] {cout << "func " << endl;};
//
//	func();
//
//	cout << add(1, 2);*/
//
//	int arr[10][3] = {0};
//
//	cout << sizeof(arr[0]) << endl;
//
//	return 0;
//}
//
//int main()
//{
//
//	int a = 10;
//	int b = 20;
//	
//	auto swap = [](int& a,int& b)mutable
//	{
//		int t = a;
//		a = b;
//		b = t;
//
//		cout << a << endl;
//		cout << b << endl;
//		cout << "---------------------------" << endl;
//	};
//	
//	swap(a,b);
//
//	cout << a << endl;
//	cout << b << endl;
//
//	return 0;
//}
//
//template<class... Args>
//void Cpp_Print(Args... args)
//{
//	cout << sizeof...(args) << endl;
//}
//
//int main()
//{
//	Cpp_Print(1,1,2);
//	return 0;
//}

//int _Cpp_print()
//{
//	cout << endl;
//	return 0;
//}

template<class T,class... Args>
int _Cpp_print(const T& val)
{
	cout << val << endl;
	return 0;
}

template<class ...Args>
void Cpp_print(Args... args)
{
	//_Cpp_print(args...);
	int arr[] = { _Cpp_print(args)... };
	cout << endl;
}
//void Cpp_print()
//{
//	cout << endl;
//}
//
//template<class T,class... Args>
//void Cpp_print(const T& val, Args... args)
//{
//	cout << val << endl;
//	Cpp_print(args...);
//}

/*
1. 函数递归展开参数包
void _cpp_print()
{
	cout << endl;
}

template<class T,class... Args>
void _cpp_print(const T& val,Args... args)
{
	cout << val << endl;
}
template<class T,class... Args>
void cpp_print(Args... args)
{
	_cpp_print(args...);
	
}

2. 逗号表达式
template<class T>
void _cpp_print(const T& val)
{
	cout << val << endl;
}

teplate<class... Args>
void cpp_print(Args... args)
{
	int arr[] = { _cpp_print(args)... }d
}


*/
//template<class T  = int >
//void print(T t = 1)
//{
//	cout << "template: " << t << endl;
//}
//
//void print(int t)
//{
//	cout << t << endl;
//}
//
//int main()
//{
//	print();
//	return 0;
//}
//#include <functional>
//
//int f1(int x, int y)
//{
//	return x + y;
//}
//
//struct f2
//{
//	int operator()(int x, int y)
//	{
//		return x + y;
//	}
//};
//
//
//int main()
//{
//	function<int(int, int)> func1 = f1;
//	function<int(int, int)> func2 = [](int x, int y) {return x + y;};
//	f2 F;
//	function<int(int, int)> func3 = F;
//
//
//	cout << func1(1, 2) << endl;
//	cout << func2(1, 2) << endl;
//	cout << func3(1, 2) << endl;
//
//
//	return 0;
//}
//#include <functional>
//class Plus
//{
//public:
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//
//int main()
//{
//	//成员函数的函数指针  &类型::函数名
//	function<int(int, int)> func1 = &Plus::plusi;
//	cout << func1(1, 2) << endl;
//	
//	//错误原因：参数不用匹配
//	//function<double(double, double)> func2 = &Plus::plusd;
//	function<double(Plus*,double, double)> func2 = &Plus::plusd;
//	Plus plus;
//	cout << func2(&plus,1.1, 2.2) << endl;
//
//	function<double(Plus,double, double)> func3 = &Plus::plusd;
//	cout << func3(Plus(), 1.1, 2.2) << endl;
//
//
//	return 0;
//}
//

//#include <functional>
//
//int Sub(int a, int b)
//{
//	return a - b;
//}
//
//int main()
//{
//	 
//	auto f1 = Sub;
//	cout << f1(10, 5) << endl;
//
//
//	auto f2 = bind(Sub, placeholders::_2, placeholders::_1);
//	cout << f2(10, 5) << endl;
//
//	return 0;
//}
//
//


//// 使用举例
//#include <functional>
//int Plus(int a, int b)
//{
//	return a + b;
//}
//class Sub
//{
//public:
//	int sub(int a, int b)
//	{
//		return a - b;
//	}
//};
//int main()
//{
//	//表示绑定函数plus 参数分别由调用 func1 的第一，二个参数指定
//	std::function<int(int, int)> func1 = std::bind(Plus, placeholders::_1,
//		placeholders::_2);
//	//auto func1 = std::bind(Plus, placeholders::_1, placeholders::_2);
//	//func2的类型为 function<void(int, int, int)> 与func1类型一样
//	//表示绑定函数 plus 的第一，二为： 1， 2
//	auto func2 = std::bind(Plus, 1, 2);
//	cout << func1(1, 2) << endl;
//	cout << func2() << endl;
//	Sub s;
//	// 绑定成员函数
//	std::function<int(int, int)> func3 = std::bind(&Sub::sub, s,
//		placeholders::_1, placeholders::_2);
//	// 参数调换顺序
//	std::function<int(int, int)> func4 = std::bind(&Sub::sub, s,
//		placeholders::_2, placeholders::_1);
//	cout << func3(1, 2) << endl;
//	cout << func4(1, 2) << endl;
//	return 0;
//}
#include <thread>
void ThreadFunc1(int& x)
{
	x += 10;
}
void ThreadFunc2(int* x)
{
	*x += 10;
}
int main()
{
	int a = 10;
	// 在线程函数中对a修改，不会影响外部实参，因为：线程函数参数虽然是引用方式，但其实际
	//引用的是线程栈中的拷贝
		thread t1(ThreadFunc1, a);
	t1.join();
	cout << a << endl;
	// 如果想要通过形参改变外部实参时，必须借助std::ref()函数
	thread t2(ThreadFunc1, std::ref(a);
	t2.join();
	cout << a << endl;
	// 地址的拷贝
	thread t3(ThreadFunc2, &a);
	t3.join();
	cout << a << endl;
	return 0;
}